#include<iostream>
#include<vector>
using namespace std;
vector<int>p;
vector<int>d;
int n,m;
int find(int x){
    if(p[x]!=x){
        int of=p[x];
        p[x]=find(p[x]);
        d[x]+=d[of];
    }
    return p[x];
}
//带权并查集 以树的视角看问题
//以权重%3来区分阶层
//相当于把竞争环链式展开 + 路径压缩
//如果x y 不再一个树 就可以确定之前没有说过矛盾的话
int main(){
    cin>>n>>m;
    p.resize(n+1,0);
    d.resize(n+1,0);
    for(int i=0;i<=n;i++){
        p[i]=i;
    }
    int res=0;
    while(m--){
        int t,x,y;
        cin>>t>>x>>y;
        if(x>n||y>n){res++;continue;}
        if(t==2&&x==y){res++;continue;}
        int px=find(x),py=find(y);
        int dx=d[x],dy=d[y];
        if(t==1){
            if(px==py&&(dx-dy)%3){//(dx%3-dy%3)%3)
                res++;
                continue;
            }
            if(px!=py){
                p[px]=py;
                d[px]=dy-dx;
            }
        }
        else{
            if(px==py&&(dx-dy-1)%3){//(dx%3-(dy+1)%3)%3)
                res++;
                continue;
            }
            if(px!=py){
                p[px]=py;
                d[px]=(dy-dx+1);
            }
        }
    }
    cout<<res;
    return 0;
}

